package com.plian.system.service.pm.annualdonationexecutemain.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.plian.Tools.*;
import com.plian.Tools.office.WordUtil;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.cache.UserCache;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.constant.yth.YthConstant;
import com.plian.system.dao.bt.baseinfo.BaseInfoDao;
import com.plian.system.entity.pm.annualdonationexecute.AnnualDonationExecute;
import com.plian.system.entity.pm.annualdonationexecutemain.AnnualDonationExecuteMain;
import com.plian.system.entity.pm.annualdonationrecord.AnnualDonationRecord;
import com.plian.system.entity.pm.annualdonationrecordmain.AnnualDonationRecordMain;
import com.plian.system.entity.sys.ApprovalMessage;
import com.plian.system.mapper.pm.annualdonationexecutemain.AnnualDonationExecuteMainMapper;
import com.plian.system.model.CommonCode;
import com.plian.system.model.R;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.mybatis.base.BaseServiceImpl;
import com.plian.system.mybatis.support.Condition;
import com.plian.system.pdf.OutPdf;
import com.plian.system.service.pm.annualdonationexecute.IAnnualDonationExecuteService;
import com.plian.system.service.pm.annualdonationexecutemain.IAnnualDonationExecuteMainService;
import com.plian.system.service.pm.annualdonationrecord.IAnnualDonationRecordService;
import com.plian.system.service.pm.annualdonationrecordmain.IAnnualDonationRecordMainService;
import com.plian.system.service.pm.property.PropertyService;
import com.plian.system.service.sys.code.IFormCodeService;
import com.plian.system.service.sys.file.FileService;
import com.plian.system.service.sys.message.IApprovalMessageService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.sys.user.ISysUserService;
import com.plian.system.vo.pm.annualdonationexecute.AnnualDonationExecuteVO;
import com.plian.system.vo.pm.annualdonationexecutemain.AnnualDonationExecuteMainVO;
import com.plian.system.vo.yth.YthResult;
import com.plian.system.wrapper.pm.annualdonationexecute.AnnualDonationExecuteWrapper;
import com.plian.system.wrapper.pm.annualdonationexecutemain.AnnualDonationExecuteMainWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

import static com.plian.system.constant.sys.FormStatusConstant.UNREVIEWED;

/**
 * 企业年度捐赠计划执行 服务实现类
 */
@Slf4j
@Service
@AllArgsConstructor
public class AnnualDonationExecuteMainServiceImpl extends BaseServiceImpl<AnnualDonationExecuteMainMapper, AnnualDonationExecuteMain> implements IAnnualDonationExecuteMainService, BaseFlowService {

    private IAnnualDonationRecordService annualDonationRecordService;

    private IAnnualDonationRecordMainService annualDonationRecordMainService;

    private IAnnualDonationExecuteService annualDonationExecuteService;

    private IFormCodeService formCodeService;

    private BaseInfoDao baseInfoDao;

    private Environment environment;

    private FileService fileService;

    private IOrgService orgService;

    private ISysUserService userService;

    private AnnualDonationExecuteWrapper annualDonationExecuteWrapper;

    private AnnualDonationExecuteMainWrapper annualDonationExecuteMainWrapper;

    @Autowired
    PropertyService propertyService;

    private IApprovalMessageService approvalMessageService;


    @Override
    public boolean saveOrUpdate(AnnualDonationExecuteMain annualDonationExecuteMain) {
        if (!Optional.ofNullable(annualDonationExecuteMain.getStatus()).isPresent()) {
            annualDonationExecuteMain.setStatus(UNREVIEWED);
        }
        boolean flag = false;
        if (!Optional.ofNullable(annualDonationExecuteMain.getId()).isPresent()) {
            annualDonationExecuteMain.setVersion("1");
            annualDonationExecuteMain.setCode(formCodeService.getCode(FormTypeConstant.PM_ANNUALDONATIONEXECUTE_FORM));
            annualDonationExecuteMain.setFormType(String.valueOf(FormTypeConstant.PM_ANNUALDONATIONEXECUTE_FORM));
            flag = true;
        }
        boolean result = super.saveOrUpdate(annualDonationExecuteMain);
        if (flag) {
            fileService.saveAll(String.valueOf(annualDonationExecuteMain.getId()), annualDonationExecuteMain.getDocList());
        } else {
            fileService.edit(String.valueOf(annualDonationExecuteMain.getId()), annualDonationExecuteMain.getDocList());
        }

        if (StringUtil.isNotBlank(annualDonationExecuteMain.getAttachIds())) {
            fileService.upYthFile(annualDonationExecuteMain.getAttachIds(), String.valueOf(annualDonationExecuteMain.getId()));
        }

        return result;
    }

    @Override
    public boolean deleteLogic(List<Long> ids) {
        for (Long id : ids) {
            AnnualDonationExecuteMain annualDonationExecuteMain = getById(id);
            if (annualDonationExecuteMain == null) {
                return false;
            } else if (annualDonationExecuteMain.getStatus() != null &&
                    (annualDonationExecuteMain.getStatus() != FormStatusConstant.STASH && annualDonationExecuteMain.getStatus() != FormStatusConstant.UNREVIEWED)) {
                return false;
            }
        }
        for (Long id : ids) {
            List<AnnualDonationExecute> list = annualDonationExecuteService.list(new QueryWrapper<AnnualDonationExecute>().eq("parent_id", id));
            list.forEach(v -> {
                AnnualDonationRecord annualDonationRecord = annualDonationRecordService.getById(v.getAnnualDonationRecordId());
                if (annualDonationRecord != null && !"".equals(annualDonationRecord.getId())) {
                    annualDonationRecord.setDef1("0");
                    annualDonationRecordService.saveOrUpdate(annualDonationRecord);
                }
            });
        }
        return super.deleteLogic(ids);
    }

    /**
     * 提交
     *
     * @param id
     * @return
     */
    @Override
    public HashMap<String, Object> commit(String id) {
        handleStatus(Long.valueOf(id), FormStatusConstant.FLOW, null);

        //将需要提交的流程变量返回，用于工作流侧
        return new HashMap<String, Object>();
    }

    /**
     * 退回
     *
     * @param id
     * @return
     */
    @Override
    public Boolean reject(String id, int formState, String comment) {
        return handleStatus(Long.valueOf(id), formState, comment);
    }

    /**
     * 审批完成
     *
     * @param id
     * @return
     */
    @Override
    public Boolean finish(String id) {
        /**
         * 设置审批人和审批时间
         */
        AnnualDonationExecuteMain annualDonationExecuteMain = getById(id);
        annualDonationExecuteMain.setApprovedUser(TokenUtil.getTokenUserId());
        Date now = DateUtil.now();
        annualDonationExecuteMain.setApprovedTime(now);
        updateById(annualDonationExecuteMain);

        return handleStatus(Long.valueOf(id), FormStatusConstant.FINISH, "审批通过");
    }

    @Override
    public String initialization(String reportCompanyId, String year) {
        String result = "";
        try {
            //创建主表数据
            List<AnnualDonationExecuteMain> list = list(new LambdaQueryWrapper<AnnualDonationExecuteMain>()
                    .eq(AnnualDonationExecuteMain::getReportCompanyId, reportCompanyId).eq(AnnualDonationExecuteMain::getYear, year));
            if (list.size() > 0) {
                result = "已存在初始化数据，请不要多次初始化";
                return result;
            } else {
                List<AnnualDonationRecordMain> annualDonationRecordMain = annualDonationRecordMainService.list(new LambdaQueryWrapper<AnnualDonationRecordMain>()
                        .eq(AnnualDonationRecordMain::getReportCompanyId, reportCompanyId)
                        .eq(AnnualDonationRecordMain::getStatus, 3).eq(AnnualDonationRecordMain::getYear, year));
                if (annualDonationRecordMain.size() > 0) {
                    AnnualDonationExecuteMain annualDonationExecuteMainbak = new AnnualDonationExecuteMain();
                    annualDonationExecuteMainbak.setVersion("1");
                    annualDonationExecuteMainbak.setYear(year);

                    List<Long> ids = new ArrayList<>();
                    for (AnnualDonationRecordMain id : annualDonationRecordMain) {
                        ids.add(id.getId());
                    }
                    String strids = StringUtils.join(ids.toArray(), ",");
                    annualDonationExecuteMainbak.setCqzcAnnualDonationRecordMainId(strids);

                    annualDonationExecuteMainbak.setReportCompanyId(reportCompanyId);
                    AnnualDonationExecuteMain annualDonationExecuteMain = new AnnualDonationExecuteMain();
                    BeanUtils.copyProperties(annualDonationExecuteMainbak, annualDonationExecuteMain);
                    saveOrUpdate(annualDonationExecuteMain);
                    result = annualDonationExecuteMain.getId().toString();
                    //查询事前备案数据

                    List<AnnualDonationRecord> annualDonationRecord = new ArrayList<>();
                    for (AnnualDonationRecordMain main : annualDonationRecordMain) {
                        annualDonationRecord.addAll(annualDonationRecordService.list(new LambdaQueryWrapper<AnnualDonationRecord>().eq(AnnualDonationRecord::getParentId, main.getId())));
                    }
                    for (int i = 0; i < annualDonationRecord.size(); i++) {
                        AnnualDonationExecute annualDonationExecute = new AnnualDonationExecute();
                        saveAnnualDonationExecute(annualDonationExecuteMain.getId(), annualDonationExecute, annualDonationRecord.get(i));
                    }

                } else {
                    result = "不存在已审的年度计划数据";
                    return result;
                }
            }
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            return "初始化失败";
        }
        return result;
    }

    @Override
    public String checkIsExisted(Long id, String code, String filingCode) {
        String result = "";
        if (Optional.ofNullable(code).isPresent()) {
            AnnualDonationExecuteMain annualDonationExecuteMain = new AnnualDonationExecuteMain();
            annualDonationExecuteMain.setCode(code);
            if (Optional.ofNullable(getOne(Condition.getQueryWrapper(annualDonationExecuteMain))).isPresent()) {
                if (id == null || !id.equals(getOne(Condition.getQueryWrapper(annualDonationExecuteMain)).getId())) {
                    result = "单据编码已存在";
                }
            }
        }
        if (Optional.ofNullable(filingCode).isPresent()) {
            AnnualDonationExecuteMain annualDonationExecuteMain = new AnnualDonationExecuteMain();
            annualDonationExecuteMain.setCode(filingCode);
            if (Optional.ofNullable(getOne(Condition.getQueryWrapper(annualDonationExecuteMain))).isPresent()) {
                if (id == null || !id.equals(getOne(Condition.getQueryWrapper(annualDonationExecuteMain)).getId())) {
                    result = "单据备案编号已存在";
                }
            }
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public boolean submit(AnnualDonationExecuteMain annualDonationExecuteMain) {

        boolean result = saveOrUpdate(annualDonationExecuteMain);
        if (Optional.ofNullable(annualDonationExecuteMain.getAnnualDonationExecutes()).isPresent() && !annualDonationExecuteMain.getAnnualDonationExecutes().isEmpty()) {
            annualDonationExecuteMain.getAnnualDonationExecutes().forEach(v -> {
                v.setParentId(annualDonationExecuteMain.getId());
                AnnualDonationRecord annualDonationRecord = annualDonationRecordService.getById(v.getAnnualDonationRecordId());
                if (Optional.ofNullable(v.getIsDeleted()).isPresent() && v.getIsDeleted().intValue() == 1) {
                    if (annualDonationRecord != null) {
                        annualDonationRecord.setDef1("0");
                        annualDonationRecordService.saveOrUpdate(annualDonationRecord);
                    }
                    annualDonationExecuteService.removeById(v.getId());
                } else {
                    if (annualDonationRecord != null && !"".equals(annualDonationRecord.getId())) {
                        annualDonationRecord.setDef1("1");
                        annualDonationRecordService.saveOrUpdate(annualDonationRecord);
                    }
                    annualDonationExecuteService.saveOrUpdate(v);
                }
            });
        }
        return result;
    }


    @Override
    public Boolean changeAll(Long id) {
        List<AnnualDonationExecuteMain> list = list(new QueryWrapper<AnnualDonationExecuteMain>().eq("id", id));
        if (list.size() <= 0) {
            return false;
        } else {
            saveOrUpdate(list.get(0));
            //获取计划主表数据
            List<AnnualDonationRecordMain> annualDonationRecordMain = annualDonationRecordMainService.list(new LambdaQueryWrapper<AnnualDonationRecordMain>()
                    .eq(AnnualDonationRecordMain::getReportCompanyId, list.get(0).getReportCompanyId())
                    .eq(AnnualDonationRecordMain::getStatus, 3).eq(AnnualDonationRecordMain::getYear, list.get(0).getYear()));
            if (annualDonationRecordMain.size() > 0) {
                //获取原子表数据
                List<AnnualDonationExecute> old = annualDonationExecuteService.list(new LambdaQueryWrapper<AnnualDonationExecute>().eq(AnnualDonationExecute::getParentId, list.get(0).getId()));

                List<AnnualDonationRecord> annualDonationRecord = new ArrayList<>();
                for (AnnualDonationRecordMain main : annualDonationRecordMain) {
                    annualDonationRecord.addAll(annualDonationRecordService.list(new LambdaQueryWrapper<AnnualDonationRecord>().eq(AnnualDonationRecord::getParentId, main.getId())));
                }

                for (int i = 0; i < annualDonationRecord.size(); i++) {
                    AnnualDonationExecute annualDonationExecute = new AnnualDonationExecute();
                    //以前生成的数据更新
                    for (int j = 0; j < old.size(); j++) {
                        if (old.get(j).getAnnualDonationRecordId() != null && old.get(j).getAnnualDonationRecordId().equals(annualDonationRecord.get(i).getId())) {
                            annualDonationExecute = old.get(j);
                        }
                    }
                    saveAnnualDonationExecute(id, annualDonationExecute, annualDonationRecord.get(i));
                }
            }
        }
        return true;
    }

    @Override
    public AnnualDonationExecuteMainVO setChild(AnnualDonationExecuteMainVO annualDonationExecuteMainVO) {
        if (Optional.ofNullable(annualDonationExecuteMainVO).isPresent()) {
            annualDonationExecuteMainVO.setAnnualDonationExecuteVOS(annualDonationExecuteWrapper.entityToVO(
                    annualDonationExecuteService.list(new LambdaQueryWrapper<AnnualDonationExecute>().eq(AnnualDonationExecute::getParentId, annualDonationExecuteMainVO.getId())
                            .isNotNull(AnnualDonationExecute::getAnnualDonationRecordId))));
        }
        return annualDonationExecuteMainVO;
    }

    private Boolean saveAnnualDonationExecute(Long pid, AnnualDonationExecute annualDonationExecute, AnnualDonationRecord annualDonationRecord) {
        //父节点
        annualDonationExecute.setParentId(pid);
        //参照来的计划子表主键
        annualDonationExecute.setAnnualDonationRecordId(annualDonationRecord.getId());
        annualDonationExecute.setDonationCompany(annualDonationRecord.getDonationCompany());
        annualDonationExecute.setDonationBasis(annualDonationRecord.getDonationBasis());
        annualDonationExecute.setDonationObject(annualDonationRecord.getDonationObject());
        annualDonationExecute.setDonationCause(annualDonationRecord.getDonationCause());
        annualDonationExecute.setDonationPropertyComposition(annualDonationRecord.getDonationPropertyComposition());
        annualDonationExecute.setDonationAmount(annualDonationRecord.getDonationAmount());
        annualDonationExecute.setDonationTime(annualDonationRecord.getDonationTime());
        annualDonationExecuteService.saveOrUpdate(annualDonationExecute);
        return true;
    }

    /**
     * 统一处理状态机事件方法
     *
     * @param id
     * @param updateStatus
     * @return
     */
    private Boolean handleStatus(Long id, int updateStatus, String comment) {
        try {
            AnnualDonationExecuteMain annualDonationExecuteMain = getById(id);
            annualDonationExecuteMain.setStatus(updateStatus);
            if (YthConstant.DATA_NINGBO.equals(annualDonationExecuteMain.getDataSource())) {
                if (updateStatus == FormStatusConstant.FINISH || updateStatus == FormStatusConstant.REJECT) {
                    ApprovalMessage approvalMessage = new ApprovalMessage();
                    approvalMessage.setDataSourceId(annualDonationExecuteMain.getDataSourceId());
                    approvalMessage.setOpinion(comment);
                    approvalMessage.setIsApprove(updateStatus == FormStatusConstant.FINISH ? 2 : 1);
                    approvalMessage.setIsSend(1);
                    approvalMessage.setDataSourceType(YthConstant.DATA_NINGBO);
                    approvalMessage.setFilingUserName(UserCache.userIdToName(TokenUtil.getTokenUserId()));
                    approvalMessage.setFormType(Integer.valueOf(annualDonationExecuteMain.getFormType()));
                    approvalMessage.setFilingCode(annualDonationExecuteMain.getCode());
                    approvalMessageService.save(approvalMessage);
                }
            }
            updateById(annualDonationExecuteMain);
            return true;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            return false;
        }
    }

    @Override
    public File buildpdf(Long id) {
        AnnualDonationExecuteMainVO bean = annualDonationExecuteMainWrapper.entityToVO(getById(id));
        bean = setChild(bean);
        Map<String, String> images = new HashMap<>(16);
        File file = null;

        try {
            ResourceLoader resourceLoader = new DefaultResourceLoader();
            InputStream inputStream = resourceLoader.getResource("annualdonationexecutemain.pdf").getInputStream();
            //通过将文件转换为临时文件进行操作
            File model = File.createTempFile("model", ".png");
            try {
                FileUtils.copyInputStreamToFile(inputStream, model);
            } finally {
                //关闭IO
                IOUtils.closeQuietly(inputStream);
            }
			/*InputStream inputStream2 = resourceLoader.getResource("4DB6230D1BF52D9A012171F8493CF278.png").getInputStream();
			//通过将文件转换为临时文件进行操作
			File image = File.createTempFile("logoImage1", ".png");
			try {
				FileUtils.copyInputStreamToFile(inputStream2, image);
			} finally {
				//关闭IO
				IOUtils.closeQuietly(inputStream2);
			}
			images.put("logoImage1",!image.exists()?"":image.getAbsolutePath());*/
            if (bean != null && model.exists()) {
                Map<String, Object> data = OutPdf.beanToMap(bean);

                List<AnnualDonationExecuteVO> temp = bean.getAnnualDonationExecuteVOS();
                BigDecimal sum = BigDecimal.ZERO;
                BigDecimal sumReal = BigDecimal.ZERO;
                int x = 0;
                for (; x < temp.size(); x++) {
                    data.put("a.id." + x, x + 1);
                    data.put("a.donationCompanyName." + x, temp.get(x).getDonationCompanyName());
                    data.put("a.donationBasis." + x, temp.get(x).getDonationBasis());
                    data.put("a.donationObject." + x, temp.get(x).getDonationObject());
                    data.put("a.donationCause." + x, temp.get(x).getDonationCause());
                    data.put("a.donationPropertyComposition." + x, temp.get(x).getDonationPropertyComposition());
                    data.put("a.donationAmount." + x, temp.get(x).getDonationAmount());
                    data.put("a.donationTime." + x, temp.get(x).getDonationTime());
                    data.put("a.actualDonationAmount." + x, temp.get(x).getActualDonationAmount());
                    data.put("a.actualDonationTime." + x, temp.get(x).getActualDonationTime());
                    data.put("a.inconsistencyReason." + x, temp.get(x).getInconsistencyReason());
                    if (temp.get(x).getDonationAmount() != null) {
                        sum = sum.add(temp.get(x).getDonationAmount());
                    }
                    if (temp.get(x).getActualDonationAmount() != null) {
                        sumReal = sumReal.add(temp.get(x).getActualDonationAmount());
                    }
                }
                data.put("a.id." + x, "合计");
                data.put("a.donationAmount." + x, sum);
                data.put("a.actualDonationAmount." + x, sumReal);

                String fileName = model.getPath();
                PdfReader reader = new PdfReader(fileName);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                /* 将要生成的目标PDF文件名称 */
                PdfStamper ps = new PdfStamper(reader, bos);
                /* 使用中文字体 */
                BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                ArrayList<BaseFont> fontList = new ArrayList<>();
                fontList.add(bf);

                /* 取出报表模板中的所有字段 */
                AcroFields fields = ps.getAcroFields();
                fields.setSubstitutionFonts(fontList);
                for (String key : data.keySet()) {
                    if (data.get(key) != null) {
                        String value = data.get(key).toString();
                        if (data.get(key) instanceof Date) {
                            value = processDate((Date) data.get(key));
                        }
                        fields.setField(key, value);
                    }
                }

				/*if (images!=null) {
					for (String key : images.keySet()) {
						if (!StringUtil.isEmpty(images.get(key))) {
							//待加入图片的文字域,设置为隐藏;不然会遮挡掉图片的
							OutPdf.insertImage(fields, ps, key, images.get(key));
						}
					}
				}*/
                /* 必须要调用这个，否则文档不会生成的 */
                ps.setFormFlattening(true);
                ps.close();
                File dir = new File(model.getParent());
                String classFullName = bean.getClass().getName();
                file = File.createTempFile(classFullName.substring(classFullName.lastIndexOf(".")), ".pdf", dir);
                OutputStream fos = new FileOutputStream(file);
                fos.write(bos.toByteArray());
                fos.flush();
                fos.close();
                bos.close();
            }

        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return file;
    }

    private static String processDate(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return date == null ? "" : format.format(date);
    }

    @Override
    public File createReceptFile(Long id) {
        try {
            int length = 0;
            AnnualDonationExecuteMainVO bean = annualDonationExecuteMainWrapper.entityToVO(getById(id));
            bean = setChild(bean);
            BigDecimal book = BigDecimal.ZERO;
            BigDecimal real = BigDecimal.ZERO;

            length = bean.getAnnualDonationExecuteVOS() == null ? 0 : bean.getAnnualDonationExecuteVOS().size();
            String[][] son = new String[length][11];
            for (int i = 0; i < length; i++) {
                son[i][0] = String.valueOf(i + 1);
                son[i][1] = bean.getAnnualDonationExecuteVOS().get(i).getDonationCompanyName();
                son[i][2] = bean.getAnnualDonationExecuteVOS().get(i).getDonationBasis();
                son[i][3] = bean.getAnnualDonationExecuteVOS().get(i).getDonationObject();
                son[i][4] = bean.getAnnualDonationExecuteVOS().get(i).getDonationCause();
                son[i][5] = bean.getAnnualDonationExecuteVOS().get(i).getDonationPropertyComposition();
                if (Optional.ofNullable(bean.getAnnualDonationExecuteVOS().get(i).getDonationAmount()).isPresent()) {
                    son[i][6] = bean.getAnnualDonationExecuteVOS().get(i).getDonationAmount().toString();
                    book = book.add(bean.getAnnualDonationExecuteVOS().get(i).getDonationAmount());
                } else {
                    son[i][6] = "";
                }
                if (Optional.ofNullable(bean.getAnnualDonationExecuteVOS().get(i).getActualDonationTime()).isPresent()) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
                    son[i][7] = simpleDateFormat.format(bean.getAnnualDonationExecuteVOS().get(i).getDonationTime());
                } else {
                    son[i][7] = "";
                }
                if (Optional.ofNullable(bean.getAnnualDonationExecuteVOS().get(i).getActualDonationAmount()).isPresent()) {
                    son[i][8] = bean.getAnnualDonationExecuteVOS().get(i).getActualDonationAmount().toString();
                    real = real.add(bean.getAnnualDonationExecuteVOS().get(i).getActualDonationAmount());
                } else {
                    son[i][8] = "";
                }
                if (Optional.ofNullable(bean.getAnnualDonationExecuteVOS().get(i).getActualDonationTime()).isPresent()) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
                    son[i][9] = simpleDateFormat.format(bean.getAnnualDonationExecuteVOS().get(i).getActualDonationTime());
                } else {
                    son[i][9] = "";
                }
                son[i][10] = bean.getAnnualDonationExecuteVOS().get(i).getInconsistencyReason();
            }

            Document document = new Document(new RectangleReadOnly(842F, 595F), 90, 83, 30, 40);
            FileOutputStream fs;
            BaseFont bfHeiTi;
            BaseFont bfST;
            BaseFont test;
            BaseFont bfbt;

            File pdffile = File.createTempFile(id.toString(), ".pdf");
            if (pdffile.exists()) {
                pdffile.delete();
            }

            fs = new FileOutputStream(pdffile.getPath());//getAbsolutePath
            PdfWriter.getInstance(document, fs);

            // 打开文档
            document.open();
            bfST = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            bfHeiTi = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            bfbt = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            test = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);

            // 创建了一页
            Font font_Zhengwen = new Font(bfST, 10.0f, Font.NORMAL, BaseColor.BLACK);
            // 添加标题
            Font font_Biaoti = new Font(bfHeiTi, 20.0f, Font.BOLD, BaseColor.BLACK);
            Font font_biaotou1 = new Font(test, 12.0f, Font.NORMAL, BaseColor.BLACK);
            Font font_biaotou2 = new Font(bfbt, 12.0f, Font.NORMAL, BaseColor.BLACK);

            // 创建一个段落
            String title = bean.getYear() + "年度捐赠计划执行情况表";
            Paragraph biaoti = new Paragraph(title, font_Biaoti);
            biaoti.setAlignment(1);
            biaoti.setSpacingAfter(20f);
            document.add(biaoti);

            float[] widths = {20f, 40f, 40f, 40f, 40f, 50f, 30f, 30f, 30f, 30f, 50f};// 设置表格的列宽
            PdfPTable table = new PdfPTable(widths);// 建立一个pdf表格
            table.setSpacingBefore(10f);// 设置表格上面空白宽度
            table.setSpacingAfter(0f);// 设置表格下面空白宽度
            table.setTotalWidth(750);// 设置表格的宽度
            PdfPCell cell = new PdfPCell();
            PdfPCell cell2 = new PdfPCell();
            cell.setMinimumHeight(25f);
            cell2.setMinimumHeight(25f);
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setPaddingTop(5);
            cell.setPaddingBottom(5);
            cell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell2.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell2.setPaddingTop(5);
            cell2.setPaddingBottom(5);
            //table.setLockedWidth(true);

            PdfPCell cell3 = new PdfPCell();
            PdfPCell cell4 = new PdfPCell();
            cell3.setMinimumHeight(25f);
            cell4.setMinimumHeight(25f);
            cell3.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell4.setVerticalAlignment(Element.ALIGN_MIDDLE);
            table.setLockedWidth(true);

            //正式开始
            cell3.setPhrase(new Paragraph("原备案编号：" + bean.getFilingCode(), font_Zhengwen));
            cell3.setHorizontalAlignment(Element.ALIGN_LEFT);
            cell3.disableBorderSide(13);
            cell3.setColspan(6);
            table.addCell(cell3);
            cell4.setPhrase(new Paragraph("金额单位：万元", font_Zhengwen));
            cell4.setHorizontalAlignment(Element.ALIGN_RIGHT);
            cell4.disableBorderSide(13);
            cell4.setColspan(5);
            table.addCell(cell4);

            cell.setPhrase(new Paragraph("填报单位(盖章)", font_biaotou2));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setColspan(3);
            table.addCell(cell);
            cell2.setPhrase(new Paragraph(bean.getReportCompanyName(), font_Zhengwen));
            cell2.setColspan(8);
            cell2.setHorizontalAlignment(Element.ALIGN_CENTER);
            table.addCell(cell2);

            cell.setPhrase(new Paragraph("捐赠计划备案情况", font_biaotou2));
            cell.setColspan(8);
            table.addCell(cell);

            cell.setPhrase(new Paragraph("捐赠计划执行情况", font_biaotou2));
            cell.setColspan(3);
            table.addCell(cell);

            cell.setPhrase(new Paragraph("序号", font_biaotou2));
            cell.setColspan(1);
            table.addCell(cell);

            cell.setPhrase(new Paragraph("捐赠企业", font_biaotou2));
            table.addCell(cell);

            cell.setPhrase(new Paragraph("捐赠依据", font_biaotou2));
            table.addCell(cell);

            cell.setPhrase(new Paragraph("捐赠对象", font_biaotou2));
            table.addCell(cell);

            cell.setPhrase(new Paragraph("捐赠事由", font_biaotou2));
            table.addCell(cell);

            cell.setPhrase(new Paragraph("捐赠财产构成", font_biaotou2));
            table.addCell(cell);

            cell.setPhrase(new Paragraph("捐赠金额", font_biaotou2));
            table.addCell(cell);

            cell.setPhrase(new Paragraph("捐赠时间", font_biaotou2));
            table.addCell(cell);

            cell.setPhrase(new Paragraph("实际捐赠金额", font_biaotou2));
            table.addCell(cell);

            cell.setPhrase(new Paragraph("实际捐赠时间", font_biaotou2));
            table.addCell(cell);

            cell.setPhrase(new Paragraph("执行与计划不一致原因", font_biaotou2));
            table.addCell(cell);

            length = son.length < 8 ? 8 : son.length;
            for (int i = 0; i < length; i++) {
                for (int j = 0; j < 11; j++) {
                    if (i < son.length) {
                        cell2.setPhrase(new Paragraph(son[i][j], font_Zhengwen));
                    } else {
                        cell2.setPhrase(new Paragraph("", font_Zhengwen));
                    }
                    cell2.setColspan(1);
                    cell2.setRowspan(1);
                    table.addCell(cell2);
                }
            }

            cell.setPhrase(new Paragraph("合计", font_biaotou2));
            table.addCell(cell);

            cell2.setPhrase(new Paragraph("", font_Zhengwen));
            table.addCell(cell2);
            table.addCell(cell2);
            table.addCell(cell2);
            table.addCell(cell2);
            table.addCell(cell2);

            cell2.setPhrase(new Paragraph(book.toString(), font_Zhengwen));
            table.addCell(cell2);

            cell2.setPhrase(new Paragraph("", font_Zhengwen));
            table.addCell(cell2);

            cell2.setPhrase(new Paragraph(real.toString(), font_Zhengwen));
            table.addCell(cell2);

            cell2.setPhrase(new Paragraph("", font_Zhengwen));
            table.addCell(cell2);
            table.addCell(cell2);

            document.add(table);
            document.close();
            return pdffile;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return null;
    }

    @Override
    public R<AnnualDonationExecuteMainVO> getDetailObj(AnnualDonationExecuteMainVO annualDonationExecuteMainVO) {
        if (!Optional.ofNullable(annualDonationExecuteMainVO).isPresent()) {
            return new R(CommonCode.FAIL);
        }
        annualDonationExecuteMainVO.setAnnualDonationExecuteVOS(annualDonationExecuteWrapper.entityToVO(annualDonationExecuteService
                .list(new LambdaQueryWrapper<AnnualDonationExecute>().eq(AnnualDonationExecute::getParentId, annualDonationExecuteMainVO.getId())
                        .isNotNull(AnnualDonationExecute::getAnnualDonationRecordId))));
        return R.data(annualDonationExecuteMainVO);
    }

    @Override
    public List<PageData> findByIds(List<String> formIds) {
        QueryWrapper<AnnualDonationExecuteMain> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", Func.toLongList(StringUtils.join(formIds, StringPool.COMMA)));
        List<AnnualDonationExecuteMain> annualDonationExecuteMains = list(queryWrapper);
        List<AnnualDonationExecuteMainVO> annualDonationExecuteMainVOS = annualDonationExecuteMainWrapper.entityToVO(annualDonationExecuteMains);
        List<PageData> pageDataList = new ArrayList<>();
        try {
            if (CollectionUtil.isNotEmpty(annualDonationExecuteMainVOS)) {
                for (AnnualDonationExecuteMainVO vo : annualDonationExecuteMainVOS) {
                    PageData pd = new PageData();
                    pd.put("id", vo.getId());
                    pd.put("UNITNAME", vo.getReportCompanyName());
                    pd.put("APPLICANTNAME", vo.getCreateUserName());
                    pd.put("applicantId", vo.getCreateUser());
                    pd.put("applyOrganizationId", vo.getReportCompanyId());
                    pd.put("formType", FormTypeConstant.PM_ANNUALDONATIONEXECUTE_FORM);
                    pd.put("orgName", vo.getReportCompanyName());
                    pageDataList.add(pd);
                }
            }

            return pageDataList;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return pageDataList;
    }

    @Override
    public List<Integer> getFormType() {
        return Arrays.asList(FormTypeConstant.PM_ANNUALDONATIONEXECUTE_FORM);
    }

    @Override
    public void goBackToStash(String formId) {
        handleStatus(Long.valueOf(formId), UNREVIEWED, null);
    }

    @Override
    public File buildword(Long id, HttpServletResponse response) {
        AnnualDonationExecuteMainVO bean = annualDonationExecuteMainWrapper.entityToVO(getById(id));
        File file = null;
        try {
            if (bean != null) {
                Map<String, Object> data = new HashMap<>(16);
                data.put("year", bean.getYear());
                data.put("fillingCode", bean.getFilingCode());
                data.put("reportCompanyName", bean.getReportCompanyName());

                BigDecimal donationAmountCount = new BigDecimal(0);
                BigDecimal actualDonationAmountCount = new BigDecimal(0);
                AnnualDonationExecute annualDonationExecute = new AnnualDonationExecute();
                annualDonationExecute.setParentId(bean.getId());
                List<AnnualDonationExecuteVO> annualDonationExecuteVOS = annualDonationExecuteWrapper.entityToVO(annualDonationExecuteService.list(Condition.getQueryWrapper(annualDonationExecute)));
                if (CollectionUtil.isNotEmpty(annualDonationExecuteVOS)) {
                    data.put("annualDonationExecuteVOS", annualDonationExecuteVOS);
                    for (AnnualDonationExecuteVO annualDonationExecuteVO : annualDonationExecuteVOS) {
                        donationAmountCount = BigDecimalUtil.add(donationAmountCount, annualDonationExecuteVO.getDonationAmount());
                        actualDonationAmountCount = BigDecimalUtil.add(actualDonationAmountCount, annualDonationExecuteVO.getActualDonationAmount());
                    }
                }
                data.put("donationAmountCount", donationAmountCount);
                data.put("actualDonationAmountCount", actualDonationAmountCount);

                String realPath = environment.getProperty("doc.path") + id + ".doc";
                file = WordUtil.generateWord(data, realPath, "annualDonationExecuteMain.doc", "annualDonationExecuteMain.ftl");
                response.setHeader("Content-Disposition", "attachment;fileName=" + file.getName());
                InputStream inputStream = new FileInputStream(file);
                // 激活下载操作
                OutputStream os = response.getOutputStream();
                // 循环写入输出流
                byte[] b = new byte[2048];
                int length;
                while ((length = inputStream.read(b)) > 0) {
                    os.write(b, 0, length);
                }
                // 这里主要关闭。
                os.close();
                inputStream.close();
            }

        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return file;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public String saveAnnualDonationExecuteReform(String data) {
        YthResult ythResult = new YthResult();
        //成功的id集合
        List<String> successIds = new ArrayList<>();
        //失败的id集合
        List<String> failIds = new ArrayList<>();
        //失败的原因
        List<String> failReasons = new ArrayList<>();
        //将json字符串转换成list
        List<AnnualDonationExecuteMain> dataList = JSON.parseArray(data, AnnualDonationExecuteMain.class);
        //判断list是否为空
        if (CollectionUtil.isNotEmpty(dataList)) {
            //根据datasourceIds 查询出所有的数据
            List<AnnualDonationExecuteMain> list = list(new LambdaQueryWrapper<AnnualDonationExecuteMain>()
                    .in(AnnualDonationExecuteMain::getDataSourceId, dataList.stream()
                            .map(AnnualDonationExecuteMain::getDataSourceId).toArray()));
            //如果数据库中有数据，就更新，没有就新增
            for (AnnualDonationExecuteMain entity : dataList) {
                String dataSourceId = entity.getDataSourceId();
                if (CollectionUtil.isNotEmpty(list)) {
                    List<String> olIds = list.stream().map(AnnualDonationExecuteMain::getDataSourceId).collect(Collectors.toList());
                    //判断数据库中是否有数据
                    if (olIds.contains(dataSourceId)) {
                        for (AnnualDonationExecuteMain oldEntity : list) {
                            if (dataSourceId.equals(oldEntity.getDataSourceId())) {
                                successIds.add(dataSourceId);
                                entity.setId(oldEntity.getId());
                                entity.setDataSource(YthConstant.DATA_NINGBO);
                                extracted(entity);
                                submit(entity);
                                list.remove(oldEntity);
                                break;
                            }
                        }
                    } else {
                        //如果数据库中没有数据，就新增
                        entity.setDataSource(YthConstant.DATA_NINGBO);
                        extracted(entity);
                        submit(entity);
                        successIds.add(entity.getDataSourceId());
                    }
                } else {
                    entity.setDataSource(YthConstant.DATA_NINGBO);
                    extracted(entity);
                    submit(entity);
                    successIds.add(entity.getDataSourceId());
                }
            }
        } else {
            failReasons.add("数据为空");
        }
        ythResult.setSuccessIds(successIds);
        ythResult.setFailIds(failIds);
        ythResult.setFailReason(StringUtils.join(failReasons, ";"));
        //ythResult转换成json字符串
        return JSON.toJSONString(ythResult);
    }

    @Override
    public boolean checkJzjh(Long id) {
        Boolean isTwoYear=false;
        Boolean isTreeYear=false;
        Boolean bo=false;
        Boolean isTree=false;
        List<AnnualDonationExecute> executes=annualDonationExecuteService.list(new LambdaQueryWrapper<AnnualDonationExecute>()
                .eq(AnnualDonationExecute::getParentId, id));
        BigDecimal amount=new BigDecimal(0);
        if(executes!=null&&executes.size()>0){
            for (AnnualDonationExecute execute: executes) {//判断一次性捐赠金额超过五万或者累计超过100万的
                if(execute!=null&&execute.getDonationAmount()!=null){
                    if(execute.getDonationAmount().compareTo(new BigDecimal(5))>=0){
                        return true;
                    }
                    amount=amount.add(execute.getDonationAmount());
                }
            }
            if(amount.compareTo(new BigDecimal(100))>=0){
                return true;
            }

            AnnualDonationExecuteMain  annualDonationExecuteMain=this.getOne(new LambdaQueryWrapper<AnnualDonationExecuteMain>()
                    .eq(AnnualDonationExecuteMain::getId, id));
            if(annualDonationExecuteMain!=null&& StringUtil.isNotBlank(annualDonationExecuteMain.getYear())){//判断连续三年捐赠同一对象
                Integer year=Integer.valueOf(annualDonationExecuteMain.getYear());
                List<AnnualDonationExecuteMain>  lastAnnualDonationExecuteMainList=this.list(new LambdaQueryWrapper<AnnualDonationExecuteMain>()
                        .eq(AnnualDonationExecuteMain::getYear, String.valueOf(year-1)).eq(AnnualDonationExecuteMain::getStatus,3));
                if(lastAnnualDonationExecuteMainList!=null&&lastAnnualDonationExecuteMainList.size()>0){
                    List<AnnualDonationExecute> twoYearexecutes=annualDonationExecuteService.list(new LambdaQueryWrapper<AnnualDonationExecute>()
                            .eq(AnnualDonationExecute::getParentId, id));
                    for (AnnualDonationExecute execute: executes) {
                        if(getCheckExecuteList(twoYearexecutes,execute)){
                            isTwoYear=true;
                            break;
                        }
                    }
                    List<AnnualDonationExecuteMain>  lastLastAnnualDonationExecuteMainList=this.list(new LambdaQueryWrapper<AnnualDonationExecuteMain>()
                            .eq(AnnualDonationExecuteMain::getYear, String.valueOf(year-2)).eq(AnnualDonationExecuteMain::getStatus,3));
                    if(lastLastAnnualDonationExecuteMainList!=null&&lastLastAnnualDonationExecuteMainList.size()>0){
                        for (AnnualDonationExecute execute: executes) {
                            if(getCheckExecuteList(twoYearexecutes,execute)){
                                isTreeYear=true;
                                break;
                            }
                        }
                    }
                }
            }
            if(isTwoYear&&isTreeYear){//判断是否连续三年都捐赠一个企业
                return true;
            }

        }




        return bo;
    }

    public Boolean getCheckExecuteList(List<AnnualDonationExecute> list, AnnualDonationExecute annualDonationExecute){
        Boolean bo=false;
        if(list!=null&&list.size()>0){
            for (AnnualDonationExecute annualDonationExecute1: list) {
                if(annualDonationExecute1!=null&&annualDonationExecute1.getDonationObject()!=null){
                    if(annualDonationExecute.getDonationObject().equals(annualDonationExecute1.getDonationObject())){
                        bo=true;
                        break;
                    }
                }
            }
        }
        return bo;
    }

    /**
     * 将数字宁波过来的数据人员id，
     *
     * @param entity
     */
    private void extracted(AnnualDonationExecuteMain entity) {
        Map<String, String> orgSourceIds = orgService.getSourceId();
        Map<String, String> userSourceIds = userService.getSourceId();

        String reportCompanyId = orgSourceIds.get(entity.getReportCompanyId());
        String createUser = userSourceIds.get(entity.getCreateUser());
        if (StringUtils.isNotBlank(reportCompanyId)) {
            entity.setReportCompanyId(reportCompanyId);
            entity.setCreateCompanyId(reportCompanyId);
        }
        if (StringUtils.isNotBlank(createUser)) {
            entity.setCreateUser(createUser);
            entity.setUpdateUser(createUser);
        }
        entity.setCreateTime(new Date());
        entity.setUpdateTime(new Date());
        //从表
        if (CollectionUtil.isNotEmpty(entity.getAnnualDonationExecutes())) {
            entity.getAnnualDonationExecutes().forEach(item -> {
                if (StringUtils.isNotBlank(reportCompanyId)) {
                    item.setCreateCompanyId(reportCompanyId);
                }
                if (StringUtils.isNotBlank(item.getDonationCompany())) {
                    String propertyId = propertyService.findByOrgCode(item.getDonationCompany());
                    if (StringUtil.isNotBlank(propertyId)) {
                        item.setDonationCompany(propertyId);
                    }
                }
                item.setDataSource(YthConstant.DATA_NINGBO);
                // 转换年度捐赠计划id
                AnnualDonationRecord annualDonationRecord = annualDonationRecordService.getOne(Wrappers.<AnnualDonationRecord>lambdaQuery()
                        .eq(AnnualDonationRecord::getDataSourceId, item.getAnnualDonationRecordId()));
                if (Optional.ofNullable(annualDonationRecord).isPresent()) {
                    item.setAnnualDonationRecordId(annualDonationRecord.getId());
                }

            });
        }
    }

}
